package com.jlcloud.core.oauth2.utils;

import com.jlcloud.core.oauth2.exception.*;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

/**
 * OAuth2ExceptionUtil
 *
 * @author By: JlCloud <br>
 * @Package: com.jlcloud <br>
 * @CreateTime: 2024-12-03 21:45 <br>
 * @Copyright: 2021 www.jilianjituan.com Inc. All rights reserved. <br>
 * @Caution 注意：本内容仅限于冀联人力集团内部传阅，禁止外泄以及用于其他的商业目的 <br>
 */
public class OAuth2ExceptionUtil {
	private static final Map<ExceptionCode, Supplier<OAuth2Exception>> OAUTH2_EXCEPTION = new ConcurrentHashMap<>(16);

	static {
		// 初始化异常映射
		OAUTH2_EXCEPTION.put(
			ExceptionCode.INVALID_REQUEST, () -> new OAuth2Exception(ExceptionCode.INVALID_REQUEST, ExceptionCode.INVALID_REQUEST.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.USER_NOT_FOUND, () -> new UsernameNotFoundException(ExceptionCode.USER_NOT_FOUND.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.USER_TENANT_NOT_FOUND, () -> new UserInvalidException(ExceptionCode.USER_TENANT_NOT_FOUND.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.USER_TOO_MANY_FAILS, () -> new UserInvalidException(ExceptionCode.USER_TOO_MANY_FAILS.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.INVALID_USER, () -> new UserInvalidException(ExceptionCode.INVALID_USER.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.UNAUTHORIZED_USER, () -> new UserUnauthorizedException(ExceptionCode.UNAUTHORIZED_USER.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.UNAUTHORIZED_USER_TENANT, () -> new UserUnauthorizedException(ExceptionCode.UNAUTHORIZED_USER_TENANT.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.INVALID_REFRESH_TOKEN, () -> new GranterInvalidException(ExceptionCode.INVALID_REFRESH_TOKEN.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.CLIENT_NOT_FOUND, () -> new ClientNotFoundException(ExceptionCode.CLIENT_NOT_FOUND.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.INVALID_CLIENT, () -> new ClientInvalidException(ExceptionCode.INVALID_CLIENT.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.INVALID_CLIENT_REDIRECT_URI, () -> new ClientInvalidException(ExceptionCode.INVALID_CLIENT_REDIRECT_URI.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.UNAUTHORIZED_CLIENT, () -> new ClientUnauthorizedException(ExceptionCode.UNAUTHORIZED_CLIENT.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.UNSUPPORTED_GRANT_TYPE, () -> new OAuth2Exception(ExceptionCode.UNSUPPORTED_GRANT_TYPE, ExceptionCode.UNSUPPORTED_GRANT_TYPE.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.INVALID_GRANTER, () -> new GranterInvalidException(ExceptionCode.INVALID_GRANTER.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.INVALID_SCOPE, () -> new OAuth2Exception(ExceptionCode.INVALID_SCOPE, ExceptionCode.INVALID_SCOPE.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.SERVER_ERROR, () -> new OAuth2Exception(ExceptionCode.SERVER_ERROR, ExceptionCode.SERVER_ERROR.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.ACCESS_DENIED, () -> new OAuth2Exception(ExceptionCode.ACCESS_DENIED, ExceptionCode.ACCESS_DENIED.getMessage(), new Throwable())
		);
		OAUTH2_EXCEPTION.put(
			ExceptionCode.TEMPORARILY_UNAVAILABLE, () -> new OAuth2Exception(ExceptionCode.TEMPORARILY_UNAVAILABLE, ExceptionCode.TEMPORARILY_UNAVAILABLE.getMessage(), new Throwable())
		);
	}

	/**
	 * 根据错误代码抛出异常
	 *
	 * @param code 错误代码
	 */
	public static void throwFromCode(int code) {
		Supplier<OAuth2Exception> exceptionSupplier = OAUTH2_EXCEPTION.get(ExceptionCode.of(code));
		if (exceptionSupplier != null) {
			throw exceptionSupplier.get();
		} else {
			throw new UserInvalidException(ExceptionCode.INVALID_USER.getMessage(), new Throwable());
		}
	}

}
